home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************************************
- *
- *
- * MacZoop - "the framework for the rest of us"
- *
- *
- *
- * ZResourceFile.cpp -- a generic resource file/manager object
- *
- *
- *
- *
- *
- * © 1997, Graham Cox
- *
- *
- *
- *
- *************************************************************************************************/
-
- #include "ZResourceFile.h"
- #include "MacZoop.h"
-
- static FSSpec gDummySpec = { 0, 0, "\p" };
-
- /*-----------------------------*** CONSTRUCTORS ***----------------------------------*/
-
- ZResourceFile::ZResourceFile( const FSSpec& aSpec )
- : ZFile( aSpec )
- {
- }
-
-
- ZResourceFile::ZResourceFile( Str255 fName )
- : ZFile( fName )
- {
- }
-
-
- ZResourceFile::ZResourceFile( const short aRefNum )
- : ZFile( gDummySpec )
- {
- // if the file was opened externally (for example, applications are opened
- // by the process manager) you can construct this object with this constructor
- // to obtain a nice object interface to the resources anyway.
-
- resRefNum = aRefNum;
- }
-
-
- /*-----------------------------*** READRESOURCE ***----------------------------------*/
- /*
- get a resource with the type and ID passed, optionally detaching it
- ---------------------------------------------------------------------------------------*/
-
- Handle ZResourceFile::ReadResource( const ResType aType, const short resID, const Boolean detachIt)
- {
- Handle h = NULL;
- short saveRes;
-
- FailOSErr((resRefNum == _NOT_OPEN)? resFNotFound : noErr );
- SetResFork( &saveRes );
-
- try
- {
- h = Get1Resource( aType, resID );
- FailOSErr( ResError());
-
- if ( detachIt )
- DetachResource( h );
- }
- catch( OSErr err )
- {
- UseResFile( saveRes );
-
- throw err;
- }
-
- UseResFile( saveRes );
-
- return h;
- }
-
-
- /*-----------------------------*** READRESOURCE ***----------------------------------*/
- /*
- get an indexed resource with the type and index passed, optionally detaching it
- ---------------------------------------------------------------------------------------*/
-
- Handle ZResourceFile::ReadResource( const short index, const ResType aType, const Boolean detachIt)
- {
- Handle h = NULL;
- short saveRes;
-
- FailOSErr((resRefNum == _NOT_OPEN)? resFNotFound : noErr );
- SetResFork( &saveRes );
-
- try
- {
- h = Get1IndResource( aType, index );
- FailOSErr( ResError());
-
- if ( detachIt )
- DetachResource( h );
- }
- catch( OSErr err )
- {
- UseResFile( saveRes );
-
- throw err;
- }
-
- UseResFile( saveRes );
-
- return h;
- }
-
-
- /*-----------------------------*** READRESOURCE ***----------------------------------*/
- /*
- get a resource with the type and name passed, optionally detaching it
- ---------------------------------------------------------------------------------------*/
-
- Handle ZResourceFile::ReadResource( const ResType aType, Str255 resName, const Boolean detachIt)
- {
- Handle h = NULL;
- short saveRes;
-
- FailOSErr((resRefNum == _NOT_OPEN)? resFNotFound : noErr );
- SetResFork( &saveRes );
-
- try
- {
- h = Get1NamedResource( aType, resName );
- FailOSErr( ResError());
-
- if ( detachIt )
- DetachResource( h );
- }
- catch( OSErr err )
- {
- UseResFile( saveRes );
-
- throw err;
- }
-
- UseResFile( saveRes );
-
- return h;
- }
-
-
- /*-----------------------------*** OWNSRESOURCE ***----------------------------------*/
- /*
- does this resource handle belong to this file? (FALSE if not a resource handle)
- ---------------------------------------------------------------------------------------*/
-
- Boolean ZResourceFile::OwnsResource( Handle aResHandle )
- {
- short hf;
-
- FailOSErr((aResHandle == NULL)? paramErr : noErr );
- hf = HomeResFile( aResHandle );
-
- if ((hf == -1) ||
- (hf != resRefNum))
- return FALSE;
- else
- return TRUE;
- }
-
-
- /*------------------------------*** HASRESOURCE ***----------------------------------*/
- /*
- does this file contain a resource of the type and ID passed?
- ---------------------------------------------------------------------------------------*/
-
- Boolean ZResourceFile::HasResource( const ResType aType, const short resID )
- {
- Handle h;
- Boolean result = FALSE;
-
- SetResLoad( FALSE );
-
- try
- {
- h = GetResource( aType, resID );
-
- if( h )
- result = TRUE;
- }
- catch( OSErr err )
- {
- // do not throw this exception (return false instead)
- }
-
- SetResLoad( TRUE );
-
- return result;
- }
-
-
- /*-------------------------------*** HASRESTYPE ***----------------------------------*/
- /*
- does the file contain any resources of the type passed?
- ---------------------------------------------------------------------------------------*/
-
- Boolean ZResourceFile::HasResType( const ResType aType )
- {
- Boolean result = FALSE;
-
- try
- {
- result = ( CountResources( aType ) > 0);
- }
- catch( OSErr err )
- {
- // this exception is not thrown
- }
-
- return result;
- }
-
-
- /*----------------------------*** TOTALRESOURCES ***---------------------------------*/
- /*
- how many resources are there altogether in this file?
- ---------------------------------------------------------------------------------------*/
-
- short ZResourceFile::TotalResources()
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- short saveRes, num;
-
- SetResFork( &saveRes );
-
- num = Count1Types();
- UseResFile( saveRes );
-
- return num;
- }
-
-
- /*----------------------------*** COUNTRESOURCES ***---------------------------------*/
- /*
- how many resources of a given type are there in this file?
- ---------------------------------------------------------------------------------------*/
-
- short ZResourceFile::CountResources( const ResType aType )
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- short saveRes, num;
-
- SetResFork( &saveRes );
-
- num = Count1Resources( aType );
- UseResFile( saveRes );
-
- return num;
- }
-
-
- /*----------------------------*** GETRFATTRIBUTES ***--------------------------------*/
- /*
- return the file attributes for this resource file
- ---------------------------------------------------------------------------------------*/
-
- short ZResourceFile::GetRFAttributes()
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- return GetResFileAttrs( resRefNum );
- }
-
-
- /*----------------------------*** GETRESOURCEINFO ***--------------------------------*/
- /*
- get information about a resource (including the name)
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::GetResourceInfo( Handle aResHandle, ResType* itsType, short* itsID, Str255 itsName )
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- GetResInfo( aResHandle, itsID, itsType, itsName );
- }
-
-
- /*----------------------------*** GETRESOURCEINFO ***--------------------------------*/
- /*
- get information about a resource (not including the name)
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::GetResourceInfo( Handle aResHandle, ResType* itsType, short* itsID )
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- Str255 itsName;
-
- GetResInfo( aResHandle, itsID, itsType, itsName );
- }
-
-
- /*-----------------------------*** WRITERESOURCE ***---------------------------------*/
- /*
- add this handle to the resource file. If already part of this file, it is simply
- marked as modified and a subsequent flush or close will actually write it.
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::WriteResource( Handle aResHandle, const ResType aType, const short resID )
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- if ( OwnsResource( aResHandle ))
- ResourceModified( aResHandle );
- else
- {
- // we don't already own this resource, so we need to add a new one, or
- // perhaps modify an existing one if it's there already.
-
- short saveRes;
-
- SetResFork( &saveRes );
-
- short rID = ( resID == _UNIQUE_ID )? Unique1ID( aType ) : resID;
-
- try
- {
- if ( HasResource( aType, rID ))
- {
- // does the type and ID already exist? If so we should remove it first
-
- Handle h = Get1Resource( aType, rID );
-
- if ( h )
- {
- RemoveResource( h );
- DisposeHandle( h );
- }
- }
-
- AddResource( aResHandle, aType, rID, "\p" );
- FailOSErr( ResError());
- }
- catch( OSErr err )
- {
- UseResFile( saveRes );
-
- throw err;
- }
-
- UseResFile( saveRes );
- }
- }
-
-
- /*-----------------------------*** WRITERESOURCE ***---------------------------------*/
- /*
- add this data to the resource file. This makes a new handle, or if the type and ID
- already exists, the new data replaces the old.
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::WriteResource( Ptr data, const long length, const ResType aType, const short resID )
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
- FailOSErr(( length < 0 )? paramErr : noErr );
- FailOSErr(( data == NULL )? paramErr : noErr );
-
- // is there already a resource of the type indicated?
-
- short saveRes, rID;
- Handle h;
-
- SetResFork( &saveRes );
-
- rID = ( resID == _UNIQUE_ID )? Unique1ID( aType ) : resID;
-
- try
- {
- if ( HasResource( aType, rID ))
- {
- // yes, we already have such a resource type, so modify it
-
- h = Get1Resource( aType, rID );
-
- if ( h )
- {
- RemoveResource( h );
- DisposeHandle( h );
- }
- }
- // now add it
-
- FailNIL( h = NewHandle( length ));
-
- BlockMoveData( data, *h, length );
- AddResource( h, aType, rID, "\p" );
- FailOSErr( ResError());
-
- ReleaseResource( h );
- }
- catch( OSErr err )
- {
- UseResFile( saveRes );
-
- throw err;
- }
-
- UseResFile( saveRes );
- }
-
-
- /*-----------------------------*** DELETERESOURCE ***--------------------------------*/
- /*
- remove the resource from the file. This disposes the handle.
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::DeleteResource( Handle aResHandle )
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
- FailOSErr(( aResHandle == NULL )? paramErr : noErr );
-
- short saveRes;
-
- SetResFork( &saveRes );
- RemoveResource( aResHandle );
-
- try
- {
- FailOSErr( ResError());
- DisposeHandle( aResHandle );
- }
- catch( OSErr err )
- {
- UseResFile( saveRes );
-
- throw err;
- }
-
- UseResFile( saveRes );
- }
-
- /*-----------------------------*** DELETERESOURCE ***--------------------------------*/
- /*
- remove the resource of the given type and ID from the file.
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::DeleteResource( const ResType aType, const short resID )
- {
- Handle h;
-
- h = GetResource( aType, resID );
- DeleteResource( h );
- }
-
-
- /*--------------------------------*** DELETEALL ***----------------------------------*/
- /*
- remove all resources. This actually sets the length of the resource fork to zero
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::DeleteAll()
- {
- // warning- use with extreme caution!
-
- Boolean wasOpen = (resRefNum != _NOT_OPEN);
- short tempRef;
-
- if ( wasOpen )
- CloseResFork();
-
- resRefNum = _NOT_OPEN;
-
- try
- {
- // open the res fork as a fork without involving the resource manager,
- // and set its length to zero.
-
- FailOSErr( FSpOpenRF( &itsSpec, fsCurPerm, &tempRef ));
- FailOSErr( SetEOF( tempRef, 0 ));
- }
- catch( OSErr err )
- {
- FSClose( tempRef );
-
- throw err;
- }
-
- FSClose( tempRef );
-
- // re-open the file with resource manager so that new map is built
-
- if ( wasOpen )
- OpenResFork();
- }
-
- /*-----------------------------*** RESOURCEMODIFIED ***------------------------------*/
- /*
- the handle has been modified, mark it as such so the file is updated.
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::ResourceModified( Handle aResHandle )
- {
- ChangedResource( aResHandle );
- FailOSErr( ResError());
-
- // inhibit purging for this handle, so it gets written
- // correctly later on.
-
- HNoPurge( aResHandle );
- }
-
- /*----------------------------------*** FLUSH ***------------------------------------*/
- /*
- write out all changed resources to the disk, leaving the file open. Close will do this
- as well, then close the file.
- ---------------------------------------------------------------------------------------*/
-
- void ZResourceFile::Flush()
- {
- FailOSErr(( resRefNum == _NOT_OPEN )? resFNotFound : noErr );
-
- UpdateResFile( resRefNum );
- }
-
-
-